import type { ConfirmProps } from "@arco-design/web-react/es/Modal/confirm";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import type { FC } from "react";
import React from "react";
import App from "../App";
import { ModalHeader } from "./content";
import { ModalContext, useModalContext } from "./context";
import type { FormModalProps, ModalContainerProps } from "./types";

type ModalConfig<TModel extends object | undefined> =
	| ModalContainerProps
	| FormModalProps<TModel>;

type modalHookFunction = (config: ConfirmProps) => {
	close: () => void;
	update: (config: ConfirmProps) => void;
};

interface ModalInstance {
	returnData: unknown;
	instance: ReturnType<modalHookFunction>;
}

const modals = new Map<symbol, ModalInstance>();

export function useModal() {
	const { modal } = App.useApp();

	function create<
		TParams extends object,
		TReturn,
		TModel extends object | undefined,
	>(
		component: FC<TParams>,
		params?: TParams,
		config?: ModalConfig<TModel>,
	): Promise<TReturn> {
		function createModalContent() {
			const modalContent = React.createElement(
				component,
				params ?? ({} as TParams),
			);
			return modalContent;
		}

		return new Promise<TReturn>((resolve) => {
			const key = Symbol("Modal");
			const queryClient = new QueryClient();
			const instance = modal.info!({
				icon: null,
				title: null,
				content: (
					<QueryClientProvider client={queryClient}>
						<ModalContext.Provider value={{ key }}>
							<ModalHeader>{config?.title ?? "系统对话框"}</ModalHeader>
							{createModalContent()}
						</ModalContext.Provider>
					</QueryClientProvider>
				),
				style: {
					width: (config?.width as string | number | undefined) ?? 600,
				},
				unmountOnExit: true,
				closable: true,
				maskClosable: false,
				escToExit: false,
				footer: null,
				className: "kl-modal",
				afterClose: () => {
					const { returnData } = modals.get(key) ?? {};
					resolve(returnData as TReturn);
					modals.delete(key);
				},
			});
			modals.set(key, { returnData: null, instance });
		});
	}

	return {
		create,
	};
}

export function useModalRef() {
	const { key } = useModalContext();

	return {
		close<TReturn>(data?: TReturn) {
			const instance = modals.get(key)!.instance;
			if (data) {
				modals.set(key, { returnData: data, instance });
			}
			instance.close();
		},
	};
}
